﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Common;
using System.Linq;
using CoreEx.Common.Cache;
using LinFu.IoC.Configuration;
using LinFu.IoC.Interfaces;
using LinFu.IoC;

namespace CoreEx.Database.Client.Implementation
{
    /// <summary>
    /// Returns all configured connection strings as <see cref="DbConnectionInfo"/> instances.
    /// </summary>
    [Implements(typeof(IDbConnectionInfoProvider))]
    public class ConnectionInfoProvider : IDbConnectionInfoProvider,IInitialize
    {
        private ILazyCachedValue<IList<DbConnectionInfo>> _cache;
               
        #region IDbConnectionInfoProvider Members

        /// <summary>
        /// Returns a list of <see cref="DbConnectionInfo"/> instances that describes the 
        /// connections available to the client.
        /// </summary>
        /// <returns>An <see cref="IEnumerable{T}"/> instance that containing available <see cref="DbConnectionInfo"/> instances.</returns>
        public IEnumerable<DbConnectionInfo> GetConnections()
        {
            return _cache.GetValue(CreateConnectionInfoList);                        
        }

       
        /// <summary>
        /// Adds a new <see cref="DbConnectionInfo"/> instance.
        /// </summary>
        /// <param name="name">The name of the configured connection</param>
        /// <param name="providerName">The invariant provider name.</param>
        /// <param name="connectionString">The connection string used to connect to the database.</param>
        public void AddConnection(string name, string providerName, string connectionString)
        {
            var dbConnectionInfo = new DbConnectionInfo
                                       {Name = name, ProviderName = providerName, ConnectionString = connectionString};    
            _cache.GetValue(CreateConnectionInfoList).Add(dbConnectionInfo);
        }

        private static IList<DbConnectionInfo> CreateConnectionInfoList()
        {
            var connections = ConfigurationManager.ConnectionStrings.Cast<ConnectionStringSettings>()
                .Select(
                s =>
                new DbConnectionInfo
                    {
                        ConnectionString = s.ConnectionString,
                        Name = s.Name.Split(new[] {'.'}).Last(),
                        ProviderName = s.ProviderName
                    });
            return connections.ToList();            
        }




        #endregion

        /// <summary>
        /// Initializes this service instance.
        /// </summary>        
        public void Initialize(IServiceContainer source)
        {
            _cache = source.GetService<ILazyCachedValue<IList<DbConnectionInfo>>>();
        }
    }
}
